home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / c / gemforce / doku.txt next >
Encoding:
Text File  |  1994-09-22  |  60.6 KB  |  1,341 lines

  1.  
  2.  +-----------------------------------------+
  3.  |+---------------------------------------+|
  4.  ||  Dokumentation zur GEM-Force-Library  ||
  5.  |+---------------------------------------+|
  6.  +-----------------------------------------+
  7.  
  8.  
  9. Inhaltsverzeichnis
  10. ==================
  11.  
  12. 1 Vorwort 
  13. 2 Das Modul-Konzept 
  14. 3 Die Struktur der GEM-Force-Library
  15. 4 Modul GLOBAL
  16. 5 Modul WINDOWS
  17. 6 Modul TOS
  18.  
  19.  
  20. 1. Vorwort
  21. ==========
  22.  
  23. Die Ihnen vorliegende GEM-Force-Library für Pure C ist ein Versuch, die oftmals 
  24. langwierige GEM-Programmierung zu vereinfachen und Funktionen zur Verfügung zu 
  25. stellen, die zwar kompakt und leistungsfähig sein sollen, jedoch den 
  26. Programmierer in seiner Flexibilität nicht einschränken sollen. Aus diesem 
  27. Grund wurde - im Gegensatz zu anderen verbreiteten Libraries - keine Funktion 
  28. geschrieben, die die AES-Events empfängt (evnt_multi) und verarbeitet, ohne daß 
  29. der Programmierer direkt Zugriff darauf hat; das wäre zwar in einigen Bereichen 
  30. für den unerfahreneren Programmierer einfacher, schränkt aber auf der anderen 
  31. Seite den erfahreneren Programmierer zu sehr ein.
  32. Ich hoffe Ihnen mit der GEM-Force-Library ein Instrument an die Hand zu geben, 
  33. mit dem Sie (wenigstens mit Grundkenntnissen der GEM-Programmierung und 
  34. natürlich C bewaffnet) einfacher GEM-Programme schreiben können. Dabei sollte 
  35. es keine Rolle spielen, ob Sie fortgeschrittener Anfänger oder schon angehender 
  36. Profi sind. In jedem Fall: Viel Erfolg !
  37. An dieser Stelle möchte ich noch den Brüdern Jürgen und Dieter Geiß, den 
  38. Autoren des Buches "Vom Anfänger zum GEM-Profi", erschienen im Hüthig-Verlag, 
  39. danken. Viele der in der Library enthaltenen Funktionen lehnen sich sehr eng an 
  40. die von ihnen vorgestellten Funktionen an. Ohne ihr Einverständnis wäre diese 
  41. Library in dieser Form nicht möglich gewesen. Also: Herzlichen Dank !
  42. GEM-Force wurde geschrieben von:
  43.  
  44. René Rosendahl, Software-Entwicklung
  45. Kameruner Str. 107
  46. 32791 Lage
  47. Telefon 05232/78916 (ab 17.00 Uhr !)
  48. BLZ 476 501 30 (Sparkasse Detmold)
  49. Konto 176004000
  50.  
  51. Bevor nun auf die eigentlichen Funktionen eingegangen wird, muß noch etwas 
  52. grundlegendes erklärt werden, und zwar...
  53.  
  54.  
  55. 2. Das Modul-Konzept
  56. ====================
  57.  
  58. Das in GEM-Force realisierte Modul-Konzept ist im Grunde das gleiche, das auch 
  59. in dem Buch "Vom Anfänger zum GEM-Profi" von den Gebrüdern Geiß vorgestellt 
  60. wurde. Es teilt Variablen und Funktionen in Bezug auf ihren Geltungsbereich in 
  61. die Arten lokal und global bezogen auf das C-Modul ein, in dem diese definiert 
  62. sind. Die lokalen Funktionen/Variablen sind modul-lokal, d. h. static, während 
  63. die globalen in allen Modulen definiert sind.
  64. Die Vorgehensweise ist folgende:
  65. 1. Alle globalen Funktionen und Variablen werden mit "GLOBAL" gekennzeichnet 
  66. und in ein Header-File für das jeweilige Modul geschrieben.
  67. 2. Die modul-lokalen Funktionen und Variablen werden mit "LOCAL" gekennzeichnet 
  68. und im C-Source selber zu Beginn definiert.
  69. 3. Jedes Modul muß als erste Header-Datei die Datei "GFIMPORT.H" laden und dann 
  70. die Header-Dateien der Module, die "importiert" werden sollen, sowie die 
  71. normalen Standard-Header-Dateien.
  72. 4. Anschließend folgt die Header-Datei "GFEXPORT.H" und die Header-Datei des 
  73. Moduls selbst.
  74. Mit dieser Vorgehensweise ist es möglich, wie in Modula Variablen und 
  75. Funktionen bezogen auf das jeweilige Modul zu importieren bzw. exportieren.
  76. In dem Header-File  "GFIMPORT.H" werden zusätzlich noch die Funktionen min und 
  77. max, sowie der Typ BOOLEAN mit seinen Ausprägungen TRUE und FALSE definiert.
  78.  
  79.  
  80. 3. Die Struktur der GEM-Force-Library
  81. =====================================
  82.  
  83. Aufbauend auf diese Modul-Struktur gliedert sich die GEM-Force-Library (intern) 
  84. in 3 Module: das Modul GLOBAL, das Modul WINDOWS und das Modul TOS. Für jedes 
  85. dieser Module gibt es ein ein eigenes Header-File, das Sie inkludieren müssen, 
  86. wenn Sie Funktionen des jeweiligen Moduls nutzen wollen.
  87.  
  88.  
  89. 4. Modul GLOBAL
  90. ===============
  91.  
  92. Dieses Modul stellt allgemeingültige Hilfsfunktionen für die GEM-Programmierung 
  93. zur Verfügung. Soll dieses Modul von GEM-Force genutzt werden, ist die Header-
  94. Datei "GFGLOBAL.H" zu importieren. Die in diesem File enthaltenen Define-
  95. Anweisungen sind nicht so interessant; wer Interesse hat, schaue sie sich in 
  96. der Datei selbst an.
  97. Erwähnenswert sind noch folgende Typ-Definitionen, die ebenfalls in der Header-
  98. Datei enthalten sind:
  99.  
  100. typedef struct
  101. {
  102.    int x, y, w, h;
  103. } RECT;
  104.  
  105. typedef struct
  106. {
  107.    long x, y, w, h;
  108. } LRECT;
  109.  
  110. RECT und LRECT sind jeweils Typen für die Speicherung von Rechtecken.
  111.  
  112. Ein weiterer Typ ist:
  113.  
  114. typedef struct
  115. {
  116.    int     ascii_code;
  117.    int     scan_code;
  118.    BOOLEAN shift;
  119.    BOOLEAN ctrl;
  120.    BOOLEAN alt;
  121.    int     kreturn;
  122.    int     kstate;
  123. } KEYINFO;
  124.  
  125. KEYINFO enthält Informationen über eine Tastaturaktion.
  126.  
  127. Es folgt nun eine Aufzählung der enthaltenen Funktionen:
  128.  
  129.  
  130. GLOBAL BOOLEAN init_gem ( void )
  131.  
  132. Diese Funktion sollte zu Beginn aller GEM-Programme aufgerufen werden. Sie 
  133. meldet das Programm zuerst beim VDI und dann bei den AES an und füllt dabei 
  134. globale Variablen, die sich bei der GEM-Programmierung immer als nützlich 
  135. erweisen:
  136. GLOBAL int appl_id      die Application-ID der Applikation
  137. GLOBAL int phys_handle  das physikalische Workstation-Handle des Bildschirms 
  138. GLOBAL int vdi_handle   das Handle der virtuellen Bildschirm-Workstation, 
  139.                         welches für alle weiteren VDI-Aufrufe benötigt wird
  140. GLOBAL int tos          die TOS-Version GLOBAL 
  141. int colors              die Anzahl der darstellbaren Farben (monochrom = 2 !)
  142. GLOBAL RECT desk        das Rechteck des benutzbaren Bildschirms (ganzer 
  143.                         Bildschirm abzüglich Menüleiste)
  144. GLOBAL RECT clip        das aktuell eingestellte Clipping-Rechteck
  145. GLOBAL int gl_wbox, gl_hbox die Breite und Höhe der Box, die ein Zeichen des 
  146.                         Systemzeichensatzes einschießt (z. B. 8 x 16)
  147. GLOBAL int gl_wchar, gl_hchar die Breite und Höhe eines Zeichens des 
  148.                         Systemzeichensatzes
  149. GLOBAL int gl_wattr, gl_hattr  die Breite und Höhe der Box, die ein Be-
  150.                         dienelement eines Fensters einschließt (z. B. die 
  151.                         Closer-Box)
  152. GLOBAL long gdos        0, wenn kein GDOS installiert ist, sonst das Ergebnis 
  153.                         des Aufrufs von vq_vgdos (siehe auch die Einträge im 
  154.                         Header für Vergleiche !)
  155. Weiterhin werden noch folgende globale Variablen initialisiert:
  156. GLOBAL int blinkrate    Blinkrate für PopUp-Menüs (Initialwert 2)
  157. GLOBAL BOOLEAN grow_shrink Zeichnen von Grow- bzw. Shrink-Boxen bei Fenstern 
  158.                         und Dialogboxen (Initialwert TRUE)
  159. GLOBAL BOOLEAN save_bg  automatisches Sichern des Hintergrundes bei Dialogboxen 
  160.                         (Initialwert TRUE)
  161. Wie für die meisten BOOLEAN-Funktionen gilt: Die Funktion gibt TRUE zurück, 
  162. wenn alles geklappt hat, sonst FALSE.
  163.  
  164.  
  165. GLOBAL void exit_gem ( void )
  166.  
  167. Diese Funktion ist das Gegenstück zu init_gem und meldet das Programm beim GEM 
  168. ab, indem sie die geöffnete virtuelle Bildschirm-Workstation schließt, den von 
  169. einer geladenen Resource-Datei benötigten Speicherplatz wieder freigibt und 
  170. appl_exit aufruft.
  171.  
  172.  
  173. GLOBAL BOOLEAN rsc_load ( char err_norsc, char *filename )
  174.  
  175. In der Regel wird man bei GEM-Programmen mit RSC-Dateien arbeiten wollen; 
  176. deshalb bietet diese Funktion einen vereinfachten Aufruf der Funktion 
  177. rsrc_load; dazu wird die Maus als Biene dargestellt und die Datei geladen. Im 
  178. Fehlerfall ertönt ein Glockensignal und eine Fehlermeldung wird (mit Hilfe 
  179. einer Alert-Box) auf den Bildschirm gebracht. Um die Library sprachunabhängig 
  180. und individuell einsetzbar zu machen, wird keine Standard-Fehlermeldung 
  181. gemacht, sondern eine von Ihnen zu übergebende Alert-Meldung angezeigt. Im 
  182. Erfolgsfall liefert die Funktion TRUE zurück.
  183.  
  184.  
  185. GLOBAL BOOLEAN init_tree ( int index, OBJECT **tree, BOOLEAN is_dialog);
  186.  
  187. Mit Hilfe eines einzigen Funktionsaufrufes, der für jeden in Ihrer Resource-
  188. Datei enthaltenen Baum getätigt werden sollte, werden eine ganze Menge 
  189. verschiedener Dinge für die Initialisierung eines Objekt-Baumes gemacht. Zuerst 
  190. einmal wird die Adresse ermittelt; dazu wird der Parameter **tree benötigt, das 
  191. heißt ein Zeiger auf einen Zeiger auf einen Objektbaum (ein Zeiger auf einen 
  192. Zeiger ist notwendig, da der Zeiger selbst ja verändert werden soll).
  193. Des weiteren werden alle Images und Icons, die in diesem Baum enthalten sind, 
  194. ins gerätespezifische Format umgewandelt, damit deren Darstellung auch auf 
  195. Rechnern mit Grafikkarten richtig funktioniert.
  196. Besonderer Leckerbissen: Alle enthaltenen benutzerdefinierten Objekte (das sind 
  197. Check-Boxes, Radio-Buttons, Überschriftenobjekte, eine "Move-Corner" für 
  198. fliegende Dialoge und Unterstreichungen) werden fertig vorbereitet.
  199. Damit das funktionieren kann, sind ein paar Dinge notwendig: Es muß einen 
  200. globalen OBJECT-Pointer namens userimg geben, der auf einen Objektbaum zeigt, 
  201. der die Images der Check-Boxes und Radio-Buttons für die verschiedenen 
  202. Auflösungen enthält. Dazu sollte einfach der in der mitgelieferten Datei 
  203. GFUSRIMG.RSC enthaltene Dialog in Ihr eigenes Resource-File kopiert werden. Die 
  204. Objekte in diesem Baum dürfen dabei auf gar keinen Fall andere Objekt-Nummern 
  205. bekommen; am besten Sie verändern also nichts daran. Weitere Voraussetzung ist, 
  206. daß dieser Baum als aller erster mit der Funktion init_tree vorbereitet wird 
  207. (andernfalls kann später nicht auf dessen Adresse zugegriffen werden !).
  208. Wenn Sie nun benutzerdefinierte Objekte in Ihrer Resource-Datei verwenden 
  209. wollen, sollten Sie diese aus der ebenfalls mitgelieferten Datei GFOBJLIB.RSC 
  210. kopieren; hier sind normale Objekte enthalten, die als Platzhalter für die 
  211. benutzerdefinierten Objekte dienen und die bereits einen entsprechenden 
  212. extended type haben.
  213. Nach der Initialisierung mit init_tree werden dann die echten Objekte 
  214. erscheinen, wenn der Dialog am Bildschirm angezeigt wird.
  215. Der letzte Parameter is_dialog ist mit TRUE zu belegen, wenn der Objekt-Baum 
  216. ein Dialog ist, sonst mit FALSE.
  217.  
  218.  
  219. GLOBAL void dialog_on ( OBJECT *tree )
  220.  
  221. Wir bleiben bei den Dialogen: Erster Schritt bei der Dialogverarbeitung ist es 
  222. natürlich, die Dialoge erst einmal für den Benutzer sichtbar zu machen. Das 
  223. können Sie mit Hilfe dieser Funktion erledigen, welche einen Objektbaum auf den 
  224. Bildschirm zeichnet.
  225. Sie brauchen sich dabei weder um das Zentrieren des Dialogs, das Retten des 
  226. Hintergrundes, die Maus oder sonst etwas kümmern: Dies alles und noch mehr wird 
  227. automatisch erledigt. Eins ist jedoch zu beachten: Da intern nur ein einziger 
  228. Speicherblock für das Retten des Hintergrunds benutzt werden kann, dürfen 
  229. Dialoge nicht übereinander gezeichnet werden; andernfalls könnte nur der 
  230. Hintergrund des letzten richtig restauriert werden, und es gäbe Probleme beim 
  231. Freigeben dieses Speicherbereichs.
  232.  
  233.  
  234. GLOBAL void dialog_off ( OBJECT *tree )
  235.  
  236. Unschwer zu erraten: dialog_off beseitigt einen Dialog wieder vom Bildschirm 
  237. und kümmert sich ggf. um das Zurückkopieren des Hintergrundes usw.
  238.  
  239.  
  240. GLOBAL int form_dialog ( OBJECT *tree, int edit_object )
  241.  
  242. Der Aufruf dieser Funktion ersetzt das normale form_do vollständig, arbeitet 
  243. also einen Dialog ab, bis ein Exit- oder Touchexit-Button betätigt wird. 
  244. "Nebenbei" werden noch fliegende Dialoge realisiert, sofern der Dialog ein 
  245. entsprechendes Objekt enthält.
  246.  
  247.  
  248. GLOBAL int do_dialog ( OBJECT *tree, int edit_object )
  249.  
  250. Der Aufruf dieser Funktion faßt die letzten drei Funktionen zusammen: Der 
  251. Dialog wird dargestellt, verwaltet und wieder vom Bildschirm gelöscht. Sie 
  252. können also eine ganze Dialogverarbeitung mit einem einzigen Befehl durchführen 
  253. !
  254. Einen Haken hat das ganze natürlich: Wurde ein Touchexit-Button betätigt, ist 
  255. der Dialog natürlich auch vom Bildschirm verschwunden, obwohl diese Art Objekte 
  256. meist verwandt werden, wenn eine Aktion im Dialog ausgelöst werden soll, ohne 
  257. daß dieser verschwindet.
  258. Aus diesem Grund wurden die vorherigen Funktionen für den Anwender global 
  259. gehalten: So kann der Dialog dargestellt (dialog_on), in einer einfachen 
  260. Schleife solange verarbeitet werden, bis ein "echtes" Exit-Objekt (also kein  
  261. Touchexit-Objekt) betätigt wurde (form_dialog), und anschließend wieder vom 
  262. Bildschirm gelöscht werden (dialog_off). Fertig !
  263.  
  264.  
  265. GLOBAL void store_dial ( OBJECT *tree )
  266.  
  267. Jeder kennt die Dialogboxen, die zum Verlassen einen OK- und einen Abbruch-
  268. Button haben. Wird letzterer betätigt, werden die vorigen Inhalte wieder in die 
  269. Dialogbox eingetragen (was man erst beim nächsten Aufruf zu sehen bekommt) und 
  270. keine weitere Aktion ausgelöst.
  271. Dieser Mechanismus erfordert es, daß das Programm sich vor dem Verändern durch 
  272. den Benutzer alle Textfelder und Buttons merkt. Und das erfordert wieder 
  273. lästigen Programmieraufwand.
  274. Nicht so mit GEM-Force ! Obige Funktion erledigt dies für Sie, indem der 
  275. gesamte Baum durchlaufen wird und Status bzw. Inhalt aller Objekte, die die 
  276. Flags SELECTABLE oder EDITABLE haben,  in internen Arrays gespeichert werden, 
  277. und zwar bis zu 20 Buttons und 10 Textfelder mit einer maximalen Länge von 70 
  278. Zeichen.
  279.  
  280.  
  281. GLOBAL void restore_dial ( OBJECT *tree )
  282.  
  283. Wurde der Abbruch-Button betätigt, können Sie nun ganz einfach mit der Funktion 
  284. restore_dial den Dialog wieder herstellen, ohne sich um Einzelheiten kümmern zu 
  285. müssen.
  286.  
  287.  
  288. GLOBAL void draw_grow_shrink ( RECT *ende, int mode )
  289.  
  290. Meistens, wenn man Grow- oder Shrink-Boxen zeichnen möchte, ist der Start- bzw. 
  291. Endpunkt die Bildschirmmitte. Dieser Vorgang wird durch draw_grow_shrink 
  292. vereinfacht, da Sie nur noch das größere Rechteck (das Zielrechteck bei Grow- 
  293. bzw. das Quellrechteck Shrink-Boxen) angeben müssen, sowie den Parameter 
  294. FMD_GROW bzw. FMD_SHRINK der AES-Funktion form_dial. Die Bildschirmmitte wird 
  295. automatisch errechnet sowie die Boxen gezeichnet, sofern die Variable 
  296. grow_shrink den Wert TRUE hat.
  297.  
  298.  
  299. GLOBAL void hide_mouse ( void )
  300.  
  301. Nun kommen wir zu den Routinen, mit denen die Maus manipuliert werden kann. Die 
  302. hier zuerst genannte läßt die Maus verschwinden. Intern wird hierzu ein Zähler 
  303. verwaltet, der bewirkt, daß die Maus sooft ausgeschaltet werden muß, wie sie 
  304. eingeschaltet wurde, bevor sie wirklich verschwindet. Umgekehrt gilt, daß die 
  305. Maus genauso oft eingeschaltet werden muß, wie sie ausgeschaltet wurde, bevor 
  306. sie erscheint.
  307. Welchen Sinn hat das ? Zum Beispiel wird in einer Fehlerroutine die Maus 
  308. eingeschaltet, um eine Alert-Box verarbeiten zu können. Am Ende wird die Maus 
  309. wieder ausgeschaltet. So schön, so gut. Was passiert aber nun, wenn die Maus 
  310. vor Ausführen der Fehlerroutine bereits eingeschaltet war ? Würde der oben 
  311. beschriebene Mechanismus nicht verwandt, würde sie am Ende der Routine wieder 
  312. ausgeschaltet, obwohl vielleicht die aufrufende Funktion von einer 
  313. angeschalteten Maus ausgeht. Dies kann mit diesem "Maus-Stack" nicht passieren.
  314.  
  315.  
  316. GLOBAL void show_mouse ( void )
  317.  
  318. Diese Funktion schaltet die Maus erwartungsgemäß nach dem oben beschriebenen 
  319. Mechanismus wieder ein.
  320.  
  321.  
  322. GLOBAL void busy_mouse ( void )
  323.  
  324. Die Mausform "Biene" wird eingestellt. Auch für das Umschalten von Biene auf 
  325. Pfeil und umgekehrt wird ein "Maus-Stack" für die Mausform (Biene oder Pfeil) 
  326. verwendet.
  327.  
  328.  
  329. GLOBAL void arrow_mouse ( void )
  330.  
  331. Das Umschalten von Biene auf Pfeil-Form erledigt diese Funktion.
  332.  
  333.  
  334. GLOBAL void set_mouse ( int number, MFORM *addr )
  335.  
  336. Diese Routine setzt die aktuelle Mausform. Falls number 255 ist, wird auf die 
  337. benutzerdefinierte Mausform umgeschaltet, auf die addr zeigt. Für den nächsten 
  338. Befehl merkt sich die Funktion in der globalen Variablen mousenumber und 
  339. mouseform die letzte Mausform.
  340.  
  341.  
  342. GLOBAL void last_mouse ( void )
  343.  
  344. Schaltet auf die zuletzt eingeschaltete Mausform zurück.
  345.  
  346.  
  347. GLOBAL BOOLEAN select_file ( char *name, char *path, char *suffix, char *label, 
  348. char *filename )
  349.  
  350. Sollen in einem GEM-Programm Dateien geladen oder gesichert werden, kommt in 
  351. der Regel die Dateiauswahlbox ins Spiel. Um deren Aufruf zu vereinfachen wurde 
  352. diese Funktion geschrieben.
  353. name ist dabei der Name (ohne Pfad) der Datei, der in der Dateiauswahlbox als 
  354. Default vorgegeben wird.
  355. path ist der Pfad obiger Datei, der ebenfalls in der Dateiauswahlbox angezeigt 
  356. wird.
  357. suffix ist die Dateimaske einschließlich Extension, die darüber bestimmt, 
  358. welche Dateien in der Dateiauswahlbox angezeigt werden (z. B. *.*, *.C etc.).
  359. label ist der Text, der oben in der Dateiauswahlbox angezeigt wird. Dieses 
  360. Feature ist erst ab TOS 1.04 verfügbar, was aber von der Routine berücksichtigt 
  361. wird.
  362. Der Rückgabewert der Funktion ist TRUE, wenn der OK-Button betätigt wurde und 
  363. zusätzlich noch ein Dateiname ausgewählt wurde, der dann in filename steht. In 
  364. allen anderen Fällen wird FALSE zurückgegeben.
  365.  
  366.  
  367. GLOBAL void divide_filename ( char *filename, char *path, char *file)
  368.  
  369. In der letzten Funktion wurden als Eingabeparameter Pfad und Dateiname 
  370. verlangt. Damit das Aufsplitten eines vollständigen Pfadnamens möglichst 
  371. komfortabel und einfach ist, wurde diese Funktion geschaffen.
  372. Der Parameter filename gibt den vollständigen Dateinamen an. Dieser wird in 
  373. Pfad und reinen Dateinamen gesplittet und die Ergebnisse in den anderen beiden 
  374. Variablen gespeichert, und zwar genau dann, wenn der jeweilige Zeiger kein 
  375. NULL-Zeiger ist. So ist es möglich z. B. nur den Pfad, nicht aber den 
  376. Dateinamen, zu extrahieren.
  377.  
  378.  
  379. GLOBAL void call_mortimer ( char *command )
  380.  
  381. Wenn Sie stolzer Besitzer des Multi-Utilities MORTIMER der Pforzheimer Firma 
  382. OMIKRON sind, dann können Sie mit dieser Funktion Ihren Buttler aus Ihrem C-
  383. Programm heraus aufrufen, und zwar direkt mit einem Kommando (siehe MORTIMER-
  384. Handbuch). Ist kein MORTIMER installiert, bewirkt der Funktionsaufruf nichts.
  385.  
  386.  
  387. GLOBAL void do_state (OBJECT *tree, int obj, unsigned int state )
  388. GLOBAL void undo_state (OBJECT *tree, int obj, unsigned int state)
  389.  
  390. Jetzt kommen wir zu den Funktionen, die sich mit der Manipulation von Objekten 
  391. beschäftigen. Die ersten beiden hier genannten befassen sich mit dem Status von 
  392. Objekten.
  393. Mit do_state können ein oder mehrere Status-Flags des Objektes obj in 
  394. Objektbaum tree gesetzt werden. Dazu sind die in AES.H definierten Flags zu 
  395. verwenden und ggf. mit "oder" zu verknüpfen.
  396. Mit undo_state können analog ein oder mehrere Status-Flags zurückgesetzt 
  397. werden.
  398.  
  399.  
  400. GLOBAL void flip_state (OBJECT *tree, int obj, unsigned int state )
  401.  
  402. Diese und alle weiteren Funktionen, die mit flip beginnen, setzen einen oder 
  403. mehrere Flags, wenn diese vorher nicht gesetzt waren, oder setzen diese zurück, 
  404. falls sie vorher gesetzt waren.
  405.  
  406.  
  407. GLOBAL int find_state (OBJECT *tree, int obj, unsigned int state )
  408.  
  409. Diese Funktion erlaubt es, nach einem Objekt zu suchen, das einen bestimmten 
  410. Status hat. Dabei wird ab dem Objekt obj gesucht. Wurde kein Objekt gefunden, 
  411. wird NIL zurückgegeben.
  412.  
  413.  
  414. GLOBAL BOOLEAN is_state (OBJECT *tree, int obj, unsigned int state )
  415.  
  416. Natürlich müssen der Status und andere Objekt-Attribute auch abgefragt werden 
  417. können. Dies geschieht mit den Objektfunktionen, die mit is beginnen.
  418.  
  419.  
  420. GLOBAL void do_flags (OBJECT *tree, int obj, unsigned int flag )
  421. GLOBAL void undo_flags (OBJECT *tree, int obj, unsigned int flag)
  422. GLOBAL void flip_flags (OBJECT *tree, int obj, unsigned int flag )
  423. GLOBAL int find_flags (OBJECT *tree, int obj, unsigned int flag )
  424. GLOBAL BOOLEAN is_flags (OBJECT *tree, int obj, unsigned int flag )
  425.  
  426. Analog zu den eben betrachteten Funktionen arbeiten diese Funktionen, die sich 
  427. anstatt mit dem Objekt-Status mit den Objekt-Flags beschäftigen.
  428.  
  429.  
  430. GLOBAL int find_type ( OBJECT *tree, int obj, unsigned int type)
  431.  
  432. Wenn Sie einmal ein Objekt eines bestimmten Typs in einem Objekt-Baum suchen, 
  433. wird Ihnen diese Funktion weiterhelfen. Auch hier kann wieder ein Start-Objekt 
  434. angegeben werden, ab dem gesucht werden soll. Wurde kein passendes Objekt 
  435. gefunden, wird NIL zurückgegeben.
  436.  
  437.  
  438. GLOBAL void set_rbutton ( OBJECT *tree, int obj, int lower,int upper )
  439.  
  440. Will man einen Radio-Button selektieren, müssen vorher alle anderen Radio-
  441. Buttons deselektiert werden. Dies erledigt diese Funktion automatisch. Neben 
  442. dem Objekt, das selektiert werden soll müssen daher noch der erste und der 
  443. letzte der zusammengehörigen Radio-Buttons angegeben werden. Objekte, die sich 
  444. zwar durch ihre Objekt-Nummer zwischen diesen Grenzen befinden, aber keine 
  445. Radio-Buttons sind (was immer mal passieren kann), werden dabei nicht 
  446. verändert.
  447.  
  448.  
  449. GLOBAL int get_rbutton ( OBJECT *tree, int obj )
  450.  
  451. Natürlich muß man auch Radio-Buttons abfragen können. Dazu dient diese Routine, 
  452. der außer der Adresse des Objekt-Baums auch noch ein Objekt angegeben werden 
  453. muß, ab dem gesucht wird. Voraussetzung ist allerdings, daß auch wirklich ein 
  454. Radio-Button selektiert ist.
  455.  
  456.  
  457. GLOBAL void deselect_obj ( OBJECT *obj, int ind )
  458.  
  459. Eine fast überflüssige Funktion (kann durch undo_state mit entsprechenden 
  460. Parametern ersetzt werden), aber es gibt sie trotzdem. Wie der Name bereits 
  461. verrät deselektiert sie Objekte.
  462.  
  463.  
  464. GLOBAL void set_te_ptext ( OBJECT *obj, int ind, const char *str )
  465.  
  466. Diese nützliche Routine kopiert einen String in ein Textobjekt. Dabei wird die 
  467. maximale Länge des Objektes berücksichtigt und nötigenfalls der String gekürzt.
  468.  
  469.  
  470. GLOBAL void objc_rect ( OBJECT *tree, int obj, RECT *rect, BOOLEAN calc_border)
  471.  
  472. In vielen Fällen kann es nützlich sein, ein Rechteck zu ermitteln, das ein 
  473. bestimmtes Objekt einhüllt. Dies tut obige Funktion, wobei das ermittelte 
  474. Rechteck anschließend in rect steht. Der letzte Parameter gibt dabei noch an, 
  475. ob der Rand bei Objekten des Typs G_BOX, G_IBOX, G_BOXCHAR mit berücksichtigt 
  476. werden soll. Zu diesem Rand gehören auch die Attribute SHADOWED und OUTLINED.
  477.  
  478.  
  479. GLOBAL void text_default ( void )
  480.  
  481. Oftmals, wenn man Text mit Hilfe von VDI-Funktionen ausgeben will, muß man 
  482. vorher mühsam den Textstil, den Font richtiger Größe, die Ausrichtung u. v. m. 
  483. einstellen, obwohl man eigentlich den Text nur "ganz normal" ausgeben möchte. 
  484. Abhilfe schafft da diese Funktion, die alle diese Attribute auf Default-Werte 
  485. zurücksetzt und den Standard-Systemfont (z. B. 8 x 16 bei monochrom, 
  486. hochauflösend) einstellt.
  487.  
  488.  
  489. GLOBAL void line_default ( void )
  490.  
  491. Das gleiche in grün (?!), diesmal nur für die Ausgabe von Linien.
  492.  
  493.  
  494. GLOBAL void bell( void )
  495.  
  496. In den meisten Programmen macht sich ein kleiner "Ping" hier und da ganz gut 
  497. (z. B. wenn ein Fehler aufgetreten ist). Dies erledigt die Funktion bell.
  498.  
  499.  
  500. GLOBAL void rect2array ( const RECT *rect, int *array )
  501. GLOBAL void array2rect ( const int *array, RECT *rect )
  502.  
  503. Alle Jahre wieder kommt man in die Verlegenheit, mit Rechtecken und 
  504. verschiedenen Arten von Arrays herumzuwirbeln. Um Ihnen einen Großteil dieser 
  505. Arbeit abzunehmen folgen nun eine ganze Reihe von Funktionen, die sich mit 
  506. Rechtecken auseinandersetzen.
  507. Die ersten beiden kopieren den Inhalt eines Rechtecks in ein Array, das eine 
  508. Punktliste enthalten soll  (also x1, y1, x2 und y2), und umgekehrt. Die dazu 
  509. notwendigen Umrechnungen werden dabei automatisch durchgeführt.
  510.  
  511.  
  512. GLOBAL void xywh2array  ( int x, int y, int w, int h, int *array )
  513. GLOBAL void array2xywh  ( const int *array, int *x, int *y, int *w, int *h )
  514. GLOBAL void xywh2rect ( int x, int y, int w, int h, RECT *rect )
  515. GLOBAL void rect2xywh ( const RECT *rect, int *x, int *y, int *w, int *h)
  516.  
  517. Manchmal hat man Position, Breite und Höhe eines Rechtecks auch in getrennten 
  518. Variablen gespeichert (x, y, w und h) und möchte sie nun in ein Array oder ein 
  519. Rechteck kopieren oder umgekehrt. Auch hierfür gibt es entsprechende 
  520. Funktionen.
  521.  
  522.  
  523. GLOBAL BOOLEAN rc_intersect (const RECT *p1, RECT *p2)
  524.  
  525. Besonders im Rahmen der Fensterverwaltung kommt es vor, daß Rechtecke 
  526. miteinander geschnitten werden müssen. Dies erledigt diese Routine für Sie, 
  527. wobei das Ergebnis im zweiten übergebenen Rechteck abgespeichert wird und der 
  528. Rückgabewert Auskunft darüber gibt, ob sich die Rechtecke überhaupt schneiden.
  529.  
  530.  
  531. GLOBAL void rc_union ( const RECT *p1, RECT *p2)
  532.  
  533. Das Gegenstück zum Schneiden von Rechtecken ist das Vereinigen zu einem großen 
  534. Rechteck. Das Ergebnis wird wieder im zweiten Parameter abgelegt.
  535.  
  536.  
  537. GLOBAL BOOLEAN rc_equal ( const RECT *p1, const RECT *p2)
  538.  
  539. Ein Vergleich, ob zwei Rechtecke identisch sind, kann mit rc_equal durchgeführt 
  540. werden.
  541.  
  542.  
  543. GLOBAL void set_clip ( BOOLEAN set, const RECT *r )
  544.  
  545. Besonders im Zusammenhang mit Fenstern ist das Clipping angesagt. Die obige 
  546. Funktion setzt das Clipping-Rectangle (set=TRUE) oder setzt ein gesetztes 
  547. Clipping zurück (set=FALSE). Ist der übergebene Zeiger ein NULL-Zeiger, wird 
  548. der Desktop als Clipping-Bereich verwendet. Es wird auch sichergestellt, daß in 
  549. jedem Fall maximal der Desktop selbst als Clipping-Bereich verwendet wird.
  550. Damit überall im Programm das gerade aktive Clipping-Rechteck abgefragt werden 
  551. kann, wird dieses in der globalen Rechteck-Variablen clip gespeichert. 
  552.  
  553.  
  554. GLOBAL BOOLEAN inside ( int x, int y, const RECT *r )
  555.  
  556. Die letzte Rechteck-Funktion testet, ob ein bestimmter Punkt innerhalb eines 
  557. Rechtecks liegt.
  558.  
  559.  
  560. GLOBAL BOOLEAN find_menu_item ( OBJECT *menu, KEYINFO *ki, int *title, int 
  561. *item )
  562.  
  563. In den neueren GEM-Programmen ist es Gang und Gäbe, mit Tastatur-Shortcuts 
  564. Menü-Funktionen auszulösen. Im Programm muß nach einer solchen Eingabe meist 
  565. mit Hilfe von langen switch-Statements die Tastaturaktion abgefragt und die 
  566. richtige Funktion aufgerufen werden. Wird dann der Shortcut geändert, müssen 
  567. Resource-File und Programm mühsam angepaßt werden.
  568. Die Benutzer von GEM-Force haben es da viel einfacher: Die Funktion 
  569. find_menu_item erledigt bereits eine ganze Menge für den Programmierer, und 
  570. zwar wurde hier ein anderer, geschickterer Weg beschritten: Sie übergeben der 
  571. Funktion nur Informationen über das Keyboard-Event (siehe nächste Funktion), 
  572. und die Routine gibt Ihnen den gewählten Menüeintrag zurück, der direkt anhand 
  573. der Resource im Speicher gesucht wird. Dabei gibt der Return-Wert der Funktion 
  574. an, ob ein Menüeintrag gefunden wurde oder nicht. Anschließend können Sie im 
  575. Programm so verfahren, als wäre das Menü direkt ausgewählt worden.
  576. Sollen die Shortcuts geändert werden, reicht es nun, die RSC-Datei anzupassen.
  577. Die Funktion erkennt bisher folgende Tastaturkombinationen:
  578. - Control + Taste ("Dach" und Zeichen),
  579. - Shift + Funktionstaste (Pfeil nach oben und "Fxx") und
  580. - Alternate + Taste (Raute und Zeichen).
  581. Andere Kombinationen werden bisher noch nicht erkannt.
  582.  
  583.  
  584. GLOBAL void get_keyinfo ( int mkstate, int mkreturn, KEYINFO *ki )
  585.  
  586. Der in der letzten Funktion zu übergebende Zeiger ki ist ein Zeiger auf eine 
  587. KEYINFO-Struktur. Eine solche ist in Ihrem Programm anzulegen und nach einem 
  588. Tastatur-Event mit obigem Funktionsaufruf zu initialisieren. Die übergebenen 
  589. Parameter sind die gleichnamigen Rückgabeparameter der evnt_multi-Funktion der 
  590. AES.
  591.  
  592.  
  593. GLOBAL int popup_menu ( OBJECT *tree, int obj, int x, int y, int center_obj, 
  594. BOOLEAN relative, int bmsk )
  595.  
  596. Als Bonbon dieses Teiles der GEM-Force-Library noch eine handliche Funktion für 
  597. die komplette Verwaltung von PopUp-Menüs. Es wird davon ausgegangen, daß das 
  598. PopUp-Menü sich als Kind-Objekt in einem Objekt-Baum befindet. In der Regel ist 
  599. ohnehin üblich, PopUps und ähnliche Objekte in einem Objekt-Baum zu "sammeln". 
  600. Daher ist nicht nur ein Objekt-Baum anzugeben, sondern auch der Index des 
  601. Vater-Objektes des PopUp-Menüs. x und y sind Koordinaten, an denen das Menü 
  602. erscheinen soll, und zwar entweder als absolute Koordinaten (relative=FALSE) 
  603. oder als Koordinaten relativ zum Mauszeiger (relative=TRUE). Die Funktion 
  604. überwacht selbständig, daß das Menü nicht aus dem Bildschirm herausragt.
  605. Als weitere Option ist es möglich, mit center_obj ein Objekt (einen Eintrag im 
  606. PopUp-Menü) anzugeben, auf dem der Mauszeiger beim erscheinen des Menüs stehen 
  607. soll. Schließlich kann mit bmsk noch gesteuert werden, mit welchem Mausknopf 
  608. das Menü verlassen werden soll, indem eine entsprechende Maske (das 
  609. niederwertigste Bit ist der linke Mausknopf usw.) angegeben wird.
  610. Am besten, Sie experimentieren ein wenig mit den Parametern, um zu sehen, 
  611. welcher was bewirkt.
  612.  
  613.  
  614. 5. Modul WINDOWS
  615. ================
  616.  
  617. Dieses Modul stellt Funktionen für die Fensterverwaltung in Form eines Window-
  618. Managers zur Verfügung. Soll dieses GEM-Force-Modul genutzt werden, ist die 
  619. Header-Datei "GFWINDWS.H" zu importieren.
  620. Bevor näher auf die Funktionen eingegangen wird, soll das dem Window-Manager 
  621. zugrundeliegende Konzept näher erläutert werden.
  622. Zuerst einmal ist wichtig zu wissen, wie ein Fenster eingeteilt ist.
  623. Der Fensterinhalt ist in Work- und Scroll-Bereich eingeteilt. Der Work-Bereich 
  624. umfaßt immer das gesamte Fensterinnere, während der Scroll-Bereich kleiner sein 
  625. kann, so daß (wie in der Abbildung zu sehen) ein Rand entstehen kann, welcher 
  626. bei Betätigung der Slider oder ähnlichen Aktionen nicht verändert werden. 
  627. Anders der Scrollbereich, denn auf diesen beziehen sich diese Aktionen, er wird 
  628. also entsprechend gescrollt. Natürlich muß es nicht alle Ränder geben bzw. muß 
  629. es überhaupt Randbereiche geben. In letzterem Fall wäre also der Workbereich 
  630. genauso groß wie der Scrollbereich.
  631. Kommen wir nun zur grundlegendsten Struktur des Moduls WINDOWS, und zwar der 
  632. Struktur, die alle Informationen zu einem Fenster enthält:
  633.  
  634. typedef struct window
  635. {
  636.         int handle;     /* Handle für Fenster */
  637.         BOOLEAN opened; /* Fenster geöffnet */
  638.         unsigned int flags; /* Flags des Fensters */
  639.         unsigned int kind;  /* Art des Fensters */
  640.         int class;      /* Klasse des Fensters */
  641.         LRECT doc;      /* Dokumentgröße, Position */
  642.         int xfac;       /* X-Factor des Dokumentes */
  643.         int yfac;       /* Y-Factor des Dokumentes */
  644.         int xunits;     /* X-Scroll-Einheiten */
  645.         int yunits;     /* Y-Scroll-Einheiten */
  646.         RECT scroll;    /* Scrollbereich */
  647.         RECT work;      /* Arbeitsbereich */
  648.         long special;   /* für speziellen Gebrauch */
  649.         char name[128]; /* Name des Fensters */
  650.         char info[128]; /* Infozeile im Fenster */
  651.         OBJECT *object; /* Objektbaum für Fenster */
  652.         BOOLEAN (*test) (WINDOWP, int );/* Test vor einer Aktion */
  653.         void (*open) (WINDOWP);         /* Aktion vor dem Öffnen */
  654.         void (*close) (WINDOWP);        /* Aktion nach dem Schließen */
  655.         void (*delete) (WINDOWP);       /* Aktion vor dem Löschen */
  656.         void (*draw) (WINDOWP);         /* Zeichnen-Funktion */
  657.         void (*arrow) (WINDOWP,int,long,long ); /* Pfeil-Aktion */
  658.         void (*snap) (WINDOWP, RECT *, int );   /* Schnapp-Aktion */
  659.         void (*top) (WINDOWP);          /* Aktion nach Top */
  660.         void (*untop) (WINDOWP);        /* Aktion vor Untop */
  661. } WINDOW;
  662.  
  663. Der hier vielfach vorkommende Typ WINDOWP ist als Zeiger auf die Struktur 
  664. WINDOW definiert. Wer hier über Formulierungen wie "BOOLEAN (*test) (WINDOWP, 
  665. int );" stolpert und diese nicht deuten kann: Hier wird eine hervorragende 
  666. Eigenschaft der Programmiersprache C genutzt, und zwar die Speicherung von 
  667. Zeigern auf Funktionen. Eine Zuweisung an einen solchen Zeiger würde über den 
  668. Namen der Funktion geschehen, denn der Name einer Funktion ist ein Zeiger auf 
  669. dieselbe (ähnlich den Arrays). Ein Referenzieren eines solchen Zeigers mit 
  670. Hilfe des "*"-Operators würde eine solche Funktion aufrufen. Für weitergehende 
  671. Informationen zu diesem Thema sei auf einschlägige C-Literatur verwiesen.
  672. Die einzelnen Struktur-Elemente haben folgende Bedeutung:
  673.  
  674. int handle
  675. Dies ist das Handle, das bei den AES ein Fenster identifiziert und über das mit 
  676. AES-Funktionen auf Fenster zugegriffen wird.
  677.  
  678. BOOLEAN opened
  679. Der Zustand des Fensters, nämlich ob es geöffnet ist oder nicht.
  680.  
  681. unsigned int flags
  682. Verschiedene Flags, die das Verhalten des Fensters beeinflussen. Die Flags 
  683. werden vom Window-Manager weitestgehend selbst gesetzt und verwaltet. Dabei 
  684. existieren folgende Flags:
  685. # define WI_NONE        0x0000  /* Keine Flags */
  686. # define WI_FULLED      0x0001  /* Fenster auf voller Groesse */
  687. # define WI_LOCKED      0x0002  /* Fenster gelockt */
  688. # define WI_FIRSTDRW    0x0004  /* Fenster erstesmal gezeichnet */
  689. # define WI_ONTOP       0x0010  /* Fenster ist oben */
  690. # define WI_NOTOP       0x0020  /* Fenster darf nicht nach oben */
  691. # define WI_RESIDENT    0x0040  /* Fenster resident */
  692. # define WI_NOSCROLL    0x0100  /* kein Scrolling */
  693.  
  694. unsigned int kind
  695. Informationen darüber, welche Fensterelemente das Fenster hat (siehe AES.H). 
  696. Der Einfachheit befindet sich in GFWINDWS.H noch das Makro ALL für alle 
  697. Fensterelemente.
  698.  
  699. int class
  700. Die Klasse des Fensters, d. h. die Zuordnung zu einer Klasse von Fenstern, die 
  701. die gleichen Eigenschaften haben. Die Klasse kann vom Benutzer frei definiert 
  702. werden. Nur die Klasse CL_TEXT wird von GEM-Force genutzt und bezeichnet Text-
  703. Fenster.
  704.  
  705. LRECT doc
  706. Fenster zeigen in der Regel den Ausschnitt eines größeren Objektes an, sei es 
  707. ein Dokument, eine Grafik etc. Ausgehend von dieser Überlegung wird in doc.w 
  708. und doc.h die Größe dieses Dokuments angegeben, und zwar in Einheiten (Pixel 
  709. bei Bildern, Buchstaben bei Text-Dokumenten usw.). doc.x und doc.y geben die 
  710. aktuelle Position des Fenster-Ausschnitts  innerhalb des Dokumentes an.
  711.  
  712. int xfac, yfac
  713. Da die Angaben in den letzten beschrieben Variablen sich immer auf Einheiten 
  714. (Buchstaben, Pixel usw.) beziehen, wird noch die Information benötigt, wieviele 
  715. Pixel eine Einheit umfaßt, und zwar sowohl in x- als auch in y-Richtung. 
  716. Minimal kann hier jeweils eine 1 eingetragen werden. Bei Buchstaben des 
  717. Systemzeichensatzes wären die beiden Werte z. B. 8 und 16.
  718.  
  719. int xuntits, yuntits
  720. Soll in einem Dokument gescrollt werden, muß bekannt sein, um wieviel Einheiten 
  721. sich der Bildausschnitt verschiebt, wenn ein Pfeil im Fensterrandbereich 
  722. angeklickt wird. Diese Information wird für x- und y-Richtung in obigen 
  723. Variablen abgelegt.
  724.  
  725. RECT scroll
  726. Die Größe des weiter oben beschriebenen Scroll-Bereichs wird in dieser Variable 
  727. gespeichert. Maximal kann er die Größe des Work-Bereichs annehmen.
  728.  
  729. RECT work
  730. Analog dazu die Größe des Work-Bereichs.
  731.  
  732. long special
  733. Wer kennt es nicht, das ob_spec-Element der AES-Objekt-Struktur. Es dient zum 
  734. Aufnehmen verschiedener Informationen, besonders Zeiger auf diverse Strukturen. 
  735. Grundvoraussetzung ist an dieser Stelle natürlich das saubere Casting auf 
  736. Zeiger des entsprechenden Typs.
  737. Die Funktion dieser Variable ist im Grunde die gleiche: Es soll die Möglichkeit 
  738. geschaffen werden, weitere Informationen einem Fenster zuzuordnen, indem man 
  739. einen Zeiger auf diese Informationen hier speichert. Natürlich kann dies auch 
  740. eine einfache long-Zahl sein. So wird z. B. für Textfenster in dieser Variablen 
  741. ein Zeiger auf ein Text-Array gespeichert.
  742.  
  743. char name[128]
  744. Damit das Kind auch einen Namen hat: der Fenstertitel.
  745.  
  746. char info[128]
  747. Der Text für die Infozeile.
  748.  
  749. OBJECT *object
  750. Eine weitere Option für ein Fenster ist es, einen Objekt-Baum darin anzeigen zu 
  751. lassen. Wenn Sie diese Möglichkeit nutzen wollen, geben Sie hier einen 
  752. entsprechenden Zeiger an. Zu beachten ist, daß das Objekt nur im Scroll-
  753. Bereich, nicht aber im Randbereich (sofern überhaupt vorhanden) gezeichnet 
  754. wird.
  755. Viele Aktionen (z. B. das Zeichnen des Objektes und das Anpassen der 
  756. Koordinaten beim Verschieben des Fensters) werden Ihnen vom Window-Manager 
  757. abgenommen, so daß Sie sich nur noch um die wichtigen Dinge kümmern müssen. Am 
  758. besten Sie probieren es einfach mal aus.
  759.  
  760. BOOLEAN (*test) ( WINDOWP window, int action )
  761. Hier kommen wir endlich zum ersten in der Struktur enthaltenen Zeiger auf eine 
  762. Funktion. (Noch eine kurze Anmerkung: Wenn Sie Ihre eigenen Funktionen in 
  763. diesen Zeigern einhängen, ist darauf zu achten, daß diese Funktionen jeweils 
  764. die Parameter entgegennehmen müssen, die im Prototypen beschrieben sind ! Falls 
  765. Sie keine Funktion einhängen wollen, lassen Sie einfach den Initialwert NULL im 
  766. Zeiger stehen.)
  767. Diese Routine wird vom Window-Manager aufgerufen, bevor ein Fenster geschlossen 
  768. oder gelöscht wird. Der zweite Parameter gibt dabei die Aktion an, die gerade 
  769. ausgeführt werden soll (DO_CLOSE, DO_DELETE). Sie können in der eingehängten 
  770. Funktion nun testen, ob die Aktion tatsächlich durchgeführt werden soll; falls 
  771. nicht geben Sie einfach FALSE zurück, andernfalls TRUE.
  772.  
  773. void (*open) ( WINDOWP window )
  774. Die Funktion wird unmittelbar vor dem Öffnen eines Fensters aufgerufen, so daß 
  775. Sie noch bestimmte Arbeiten durchführen können, bevor das Fenster wirklich 
  776. erscheint.
  777.  
  778. void (*delete) ( WINDOWP window )
  779. Die Funktion wird unmittelbar vor dem Löschen eines Fensters aufgerufen.
  780.  
  781. void (*draw) ( WINDOWP window )
  782. Dies ist wohl mit Abstand die wichtigste Routine in der Fensterstruktur, denn 
  783. sie ist für das Zeichnen des Fensterinhalts verantwortlich und wird häufig vom 
  784. Window-Manager aufgerufen. Wichtig in diesem Zusammenhang ist, daß Sie sich 
  785. nicht mehr um das Clipping kümmern müssen; das erledigt GEM-Force bereits für 
  786. Sie. Falls Sie in Ihrer Funktion Informationen über das Clipping-Rectangle 
  787. benötigen, können Sie in der globalen Variablen RECT clip nachsehen.
  788.  
  789. void (*arrow) ( WINDOWP window ,int dir,long oldpos, long newpos )
  790. Diese Funktion wird aufgerufen, wenn der Benutzer einen Pfeil angeklickt hat 
  791. oder einen Schieber bewegt oder angeklickt hat. dir gibt dabei die Richtung an 
  792. (HORIZONTAL, VERTICAL). oldpos ist die alte Position, newpos die neue Position 
  793. im Dokument (siehe doc), abhängig von dir entweder horizontal oder vertikal.
  794. Innerhalb dieser Funktion sollten
  795. 1. die neue Position innerhalb des Dokuments in doc übertragen werden,
  796. 2. die Slider neu gesetzt werden und
  797. 3. der Fensterinhalt gescrollt werden.
  798. Voraussetzung ist natürlich, daß Sie die jeweilige Scroll-Aktion erlauben 
  799. wollen; andernfalls brauchen Sie obige Arbeiten natürlich nicht zu erledigen. 
  800. Ggf. können auch noch andere sinnvolle Dinge erledigt werden, z. B. das 
  801. Vorrücken eines internen Cursors für Textzeilen u. v. m.
  802.  
  803. void (*snap) ( WINDOWP window, RECT *new, int mode )
  804. Wird ein Fenster bewegt oder vergrößert/verkleinert, ist es oft sinnvoll, das 
  805. Fenster auf eine bestimmte Position oder Größe einzurasten (z. B. bei 
  806. Textfenstern auf ganze Buchstaben und auf eine durch 8 teilbare x-Position). 
  807. new gibt in diesem Zusammenhang die "angeforderte" Größe und Position des 
  808. gesamten Fensters an und kann von Ihnen in Ihrer Funktion verändert werden. 
  809. mode zeigt an, ob das Fenster bewegt (MOVED) oder in seiner Größe verändert 
  810. (SIZED) oder beides wurde.
  811. Zu beachten ist, daß beim ersten Öffnen eines Fensters kein Snapping 
  812. stattfindet; Sie müssen also selbst Sorge dafür tragen, daß das Fenster zu 
  813. diesem Zeitpunkt die richtige Größe und Position hat !
  814.  
  815. void (*top) (WINDOWP window)
  816. Wenn ein Fenster nach oben gebracht wird, so wird diese Funktion angesprungen. 
  817. Dies kann in zwei Fällen passieren:
  818. 1. Die AES senden die Message WM_TOPPED an die Applikation.
  819. 2. Ein Fenster wird geschlossen, und das bis dahin zweitoberste Fenster kommt 
  820. nach oben. In einem solchen Fall sorgt GEM-Force dafür, daß diese Routine für 
  821. das neue oberste Fenster angesprungen wird.
  822.  
  823. void (*untop) (WINDOWP window)
  824. Diese Funktion ist das Gegenstück zur letzten Funktion: Hier wird das bisher 
  825. oberste Fenster nach unten gebracht, und zwar wenn ein anderes Fenster getoppt 
  826. wird oder ein neues Fenster geöffnet wird.
  827. Da eine entsprechende Message im ATARI-GEM noch nicht implementiert ist, sorgt 
  828. GEM-Force selbst dafür.
  829.  
  830. So, geschafft. Jetzt sollten Sie das Prinzip des GEM-Force-Window-Managers 
  831. verstanden haben, so daß wir uns jetzt den "echten" Funktionen im einzelnen 
  832. zuwenden können.
  833.  
  834.  
  835. GLOBAL BOOLEAN init_windows ( char *err_nowindow, int max_reswind )
  836.  
  837. Wenn Sie Funktionen aus dem Windows-Modul von GEM-Force verwenden wollen, muß 
  838. dieses Modul zu Beginn initialisiert werden. Dies geschieht mit obiger 
  839. Funktion. Zu übergeben sind eine Alert-Meldung, die immer dann angezeigt wird, 
  840. wenn ein Fenster geöffnet werden soll, aber keines mehr zur Verfügung steht, 
  841. und die gewünschte Anzahl der maximal gleichzeitig im Speicher residenten 
  842. Fenster.
  843. Das Grundprinzip des Window-Managers ist es, Fenster mit ihrer Window-Struktur 
  844. im Speicher zu halten, unabhängig davon, ob sie geöffnet, also sichtbar, oder 
  845. geschlossen sind. Dafür muß natürlich Speicherplatz reserviert werden, wozu 
  846. wiederum die maximale Anzahl Fenster bekannt sein muß. Die tatsächlich 
  847. reservierte Anzahl kann unter Umständen (z. B. bei Speichermangel) auch kleiner 
  848. sein.
  849. Der Return-Wert ist TRUE, wenn wenigstens Speicher für ein einziges Fenster 
  850. reserviert werden konnte, FALSE sonst.
  851.  
  852.  
  853. GLOBAL void exit_windows ( void ) 
  854.  
  855. Um Ihr Programm zu terminieren sollten Sie auch diese Funktion aufrufen, denn 
  856. sie schließt alle Fenster, löscht diese und gibt den reservierten Speicher der 
  857. Fenster-Strukturen wieder frei.
  858.  
  859.  
  860. GLOBAL BOOLEAN handle_window_events ( int *msg )
  861.  
  862. Diese Funktion ist das Kernstück des Window-Managers. Sie sollte direkt nach 
  863. Ihrer evnt_multi-Schleife aufgerufen werden, wobei ein Zeiger auf den Event-
  864. Buffer übergeben wird. In ihr werden alle für den Window-Manager relevanten 
  865. (Message-) Events verarbeitet und an die einzelnen Fenster weitergeleitet. 
  866. Textfenster (siehe weiter unten) werden an dieser Stelle ebenfalls voll-
  867. automatisch verwaltet.
  868. Wurde das Event innerhalb der Funktion verarbeitet, wird TRUE zurückgegeben, 
  869. sonst FALSE.
  870. Generell gilt: GEM-Force verarbeitet in seinem Window-Manager nur Message-
  871. Events. Alle anderen Events sind vom Programmierer selbst zu verarbeiten.
  872.  
  873.  
  874. GLOBAL WINDOWP create_window ( unsigned int kind, int class )
  875.  
  876. Bevor Fenster-Events verarbeitet werden können, muß man natürlich erst einmal 
  877. Fenster produzieren. Dazu rufen Sie obige Funktion auf und übergeben ihr die 
  878. Art des gewünschten Fensters (Flags aus AES.H) sowie die Klasse des Fensters. 
  879. Die Fenster-Klasse ist eine von Ihnen frei vorzugebende Klassifizierung von 
  880. Fenstern, d. h. in der Regel ein Gruppenbegriff für eine bestimmte Art Fenster. 
  881. Nur die Klasse CL_TEXT ist bereits vordefiniert (siehe weiter unten).
  882. Als Rückgabewert der Funktion bekommen Sie einen Zeiger auf die zum Fenster 
  883. gehörige Window-Struktur. Haben Sie ein Fenster erfolgreich kreiert 
  884. (Rückgabewert ungleich NULL), sollten Sie selbst - abgesehen von Art und Klasse 
  885. - alle anderen (wichtigen) Elemente in der Fensterstruktur initialisieren. 
  886. Funktionszeiger brauchen nur dann initialisiert zu werden, wenn Sie benötigt 
  887. werden; andernfalls können Sie die NULL-Zeiger darin stehen lassen, die GEM-
  888. Force automatisch in die Struktur schreibt.
  889. Konnte kein Fenster mehr kreiert werden (nicht mehr genug Speicher, siehe 
  890. init_windows), wird die bei init_gem angegebene Alert-Meldung angezeigt.
  891.  
  892.  
  893. GLOBAL void delete_window ( WINDOWP window )
  894.  
  895. Soll ein Fenster auf Nimmer-Wiedersehen verschwinden, steht Ihnen diese 
  896. Funktion zur Verfügung. Sollte das betreffende Fenster noch geöffnet sein, wird 
  897. es vor dem Löschen noch geschlossen. Anschließend wird die Fensterstruktur 
  898. gelöscht; das Fenster ist nicht mehr existent. Ausnahme: Ist eine Testfunktion 
  899. in der Fensterstruktur eingehängt, und gibt diese FALSE zurück, wird das 
  900. Fenster nicht gelöscht.
  901.  
  902.  
  903. GLOBAL BOOLEAN open_window ( WINDOWP window )
  904.  
  905. Ein Fenster zu öffnen ist mit dieser Routine möglich. Sind noch GEM-Fenster 
  906. verfügbar, wird das Fenster gezeichnet und der gesamte Fensterinhalt mit weiß 
  907. initialisiert (Return-Wert TRUE). Andernfalls erscheint die bei init_gem 
  908. angegebene Alert-Meldung (Return-Wert FALSE).
  909. Beim Öffnen eines Fensters werden ausgehend von der Bildschirmmitte Grow-Boxes 
  910. gezeichnet, sofern die globale Variable grow_shrink den Wert TRUE hat.
  911. Wenn eine entsprechende open-Funktion in die Fensterstruktur eingehängt ist, 
  912. wird diese unmittelbar vor dem Öffnen angesprungen.
  913.  
  914.  
  915. GLOBAL void close_window ( WINDOWP window )
  916.  
  917. Dies ist das Gegenstück zur letzten Funktion. Beim Schließen eines Fensters 
  918. werden ausgehend von der Bildschirmmitte Shrink-Boxes gezeichnet, sofern die 
  919. globale Variable grow_shrink den Wert TRUE hat.
  920. Wenn eine entsprechende close-Funktion in die Fensterstruktur eingehängt ist, 
  921. wird diese unmittelbar vor dem Schließen angesprungen.
  922. Ist eine test-Funktion in der Fensterstruktur eingehängt, und gibt diese FALSE 
  923. zurück, wird das Fenster nicht geschlossen.
  924.  
  925.  
  926. GLOBAL void close_top ( void )
  927.  
  928. Das oberste Fenster wird geschlossen.
  929.  
  930.  
  931. GLOBAL void close_all ( BOOLEAN delete )
  932.  
  933. Alle GEM-Force-Fenster werden geschlossen. Ist der zweite Parameter TRUE, 
  934. werden die Fenster zusätzlich auch gelöscht.
  935.  
  936.  
  937. GLOBAL void draw_window ( WINDOWP window )
  938.  
  939. Der gesamte Fensterinhalt wird - ohne die Rechteckliste zu berücksichtigen - 
  940. neu gezeichnet; soll nur ein Teil neu gezeichnet werden, muß das Clipping 
  941. vorher entsprechend gesetzt werden. An dieser Stelle wird die von Ihnen in die 
  942. Fensterstruktur eingehängte Zeichenroutine benutzt. Ein eingehängter Objektbaum 
  943. wird automatisch gezeichnet. Die Maus wird selbständig versteckt.
  944.  
  945.  
  946. GLOBAL void redraw_window ( WINDOWP window, const RECT *area)
  947.  
  948. Ein bestimmter Bereich wird unter Berücksichtigung der Rechteckliste neu 
  949. gezeichnet. 
  950.  
  951.  
  952. GLOBAL void top_window ( WINDOWP window )
  953.  
  954. Ein Fenster wird nach oben gebracht, d. h. getoppt, sofern die Fenster-Flags 
  955. (siehe oben) dies zulassen. Eine von Ihnen eingehängte top-Funktion wird 
  956. anschließend angesprungen.
  957.  
  958.  
  959. GLOBAL void untop_window ( WINDOWP window )
  960.  
  961. Ein Fenster wird von einem anderen (nach oben gebrachten oder neu geöffneten 
  962. Fenster) erstmalig verdeckt (bzw. simuliert diese Funktion dies). Die Funktion 
  963. setzt die entsprechenden Flags und ruft ggf. eine in die Fensterstruktur 
  964. eingehängte untop-Routine auf.
  965.  
  966.  
  967. GLOBAL void scroll_window ( WINDOWP window, int dir, long delta )
  968.  
  969. Der Inhalt eines Fensters wird um eine beliebige Anzahl von Pixeln in eine 
  970. Richtung (HORIZONTAL/VERTICAL) gescrollt, wobei die Maus automatisch versteckt 
  971. wird. delta gibt dabei die Anzahl Pixel an (auch negative Werte sind möglich, 
  972. und zwar für aufwärts und links !).
  973. Verschiedenste Sonderfälle wie das Scrollen um ganze Seiten, aus dem Bildschirm 
  974. herausragende Fenster, nicht oben liegende Fenster u. ä. werden hierbei 
  975. berücksichtigt; ggf. wird die Rechteckliste berücksichtigt.
  976.  
  977.  
  978. GLOBAL void arrow_window ( WINDOWP window, int arrow, int amount)
  979.  
  980. Ein Fenster reagiert auf das Anklicken eines Pfeils oder eines Sliders usw. 
  981. arrow ist ein aus AES.H entnommenes Flag:
  982. WA_UPPAGE       Seite nach oben,
  983. WA_DNPAGE       Seite nach unten,
  984. WA_UPLINE       Zeile nach oben,
  985. WA_DNLINE       Zeile nach unten,
  986. WA_LFPAGE       Seite nach links,
  987. WA_RTPAGE       Seite nach rechts,
  988. WA_LFLINE       Zeile nach links,
  989. WA_RTLINE       Zeile nach rechts;
  990. Außerdem wird noch die Anzahl der Einheiten angegeben, um die gescrollt werden 
  991. soll.
  992. Diese Routine wird vom Window-Manager auch intern aufgerufen, wenn ein 
  993. entsprechendes Event aufgetreten ist.
  994. Es wird auch überwacht, daß nicht über den Rand hinaus gescrollt werden kann; 
  995. in solch einem Falle wird auch kein Scrolling oder Neuzeichnen ausgelöst.
  996. Nach Berechnung der neuen Position im Dokument wird die Funktion arrow der 
  997. Fensterstruktur aufgerufen.
  998. Ein in die Struktur eingeklinkter Objektbaum reagiert automatisch richtig auf 
  999. die Aktion.
  1000.  
  1001.  
  1002. GLOBAL void h_slider ( WINDOWP window, int new_value )
  1003.  
  1004. Ein Fenster reagiert auf das Bewegen des horizontalen Schiebers, wobei der 
  1005. zweite Parameter der vom GEM gelieferte neue Wert für den Schieber (0-1000) 
  1006. ist. Nach Berechnen des neuen Schieber-Wertes wird wie beim Anklicken eines 
  1007. Pfeils reagiert.
  1008.  
  1009.  
  1010. GLOBAL void v_slider ( WINDOWP window, int new_value )
  1011.  
  1012. Ein Fenster reagiert auf das Bewegen des vertikalen Schiebers, wobei der zweite 
  1013. Parameter der vom GEM gelieferte neue Wert für den Schieber (0-1000) ist. Nach 
  1014. Berechnen des neuen Schieber-Wertes wird wie beim Anklicken eines Pfeils 
  1015. reagiert.
  1016.  
  1017.  
  1018. GLOBAL void set_sliders ( WINDOWP window, int which, int mode)
  1019.  
  1020. Die Schieber-Positionen und/oder die Schieber-Größen werden gesetzt. which kann 
  1021. dabei die Werte HORIZONTAL, VERTICAL oder die Kombination beider annehmen, 
  1022. während mode Position (SLPOS) oder Größe (SLSIZE) oder beides angibt. Ein 
  1023. Neuzeichnen der Slider erfolgt nur dann, wenn sich deren Position wirklich 
  1024. verändert hat.
  1025.  
  1026.  
  1027. GLOBAL void snap_window ( WINDOWP window, RECT *new, int mode)
  1028.  
  1029. Die Funktion wird nach dem Verschieben oder Vergrößern/Verkleinern von Fenstern 
  1030. vom Window-Manager aufgerufen, kann aber im Bedarfsfall auch direkt aufgerufen 
  1031. werden. Zunächst wird geprüft, ob der linke Fenster-Rand genau am linken 
  1032. Bildschirmrand liegt; ist dies der Fall, wird die x-Position des Fensters auf -
  1033. 1 gesetzt, wodurch der Fenster-Workbereich genau auf x-Position 0 anfängt. 
  1034. Weiterhin wird verhindert, daß ein Fenster zu klein wird.
  1035. Ist in der Fensterstruktur eine snap-Funktion eingehängt, wird diese 
  1036. aufgerufen, so daß der Programmierer das genaue Einrasten vornehmen kann.
  1037. new ist dabei die neue Position bzw. Größe des Fensters, während mode angibt, 
  1038. ob das Fenster bewegt (MOVED) oder in seiner Größe verändert (SIZED) oder 
  1039. beides wurde.
  1040. Voraussetzung bei Aufruf dieser Funktion ist, daß das betreffende Fenster 
  1041. sichtbar am Bildschirm, d. h. opened ist, da hier intern mit AES-Funktionen 
  1042. gearbeitet wird, ein Fenster allerdings erst beim open_window für die AES 
  1043. kreiert (wind_create) und damit existent wird ! Ein geschlossenes Fenster hat 
  1044. somit kein AES-Handle. Konsequenz: Noch nicht geöffnete Fenster können nur von 
  1045. Hand "gesnappt" werden.
  1046.  
  1047.  
  1048. GLOBAL void full_window ( WINDOWP window )
  1049.  
  1050. "Ich weiß, was Sie sagen wollen, und Sie haben Recht...", so die Worte eines 
  1051. bekannten Serienhelden. Es ist offensichtlich, was diese Funktion tut: Das 
  1052. betreffende Fenster wird auf seine maximale Größe gebracht, wobei sowohl Grow-
  1053. Boxes gezeichnet werden (sofern grow_shrink auf TRUE steht) als auch die snap-
  1054. Funktion aufgerufen wird.
  1055.  
  1056.  
  1057. GLOBAL void size_window ( WINDOWP window, const RECT *new)
  1058.  
  1059. Das Fenster wird auf eine neue Größe gesetzt; zuvor wird jedoch wiederum die 
  1060. snap-Funktion aufgerufen. Die Schieber werden automatisch gesetzt.
  1061.  
  1062.  
  1063. GLOBAL void move_window ( WINDOWP window, const RECT *new )
  1064.  
  1065. Das Fenster wird auf eine neue Position gesetzt; zuvor wird wiederum die snap-
  1066. Funktion aufgerufen. Die Schieber werden wieder automatisch gesetzt.
  1067.  
  1068.  
  1069. GLOBAL void get_work ( WINDOWP window, BOOLEAN work)
  1070.  
  1071. Wurde die Position eines Fensters oder seine Größe verändert, kann mit dieser 
  1072. Funktion (sofern es GEM-Force nicht sowieso automatisch tut) der neue Work-
  1073. Bereich errechnet werden (wenn das gleichnamige Flag gesetzt ist). Gleichzeitig 
  1074. werden auch die neuen Koordinaten des Scroll-Bereichs berechnet.
  1075. In jedem Fall werden die Koordinaten eines eingehängten Objekt-Baums neu 
  1076. berechnet, d. h. einer neuen Position angepaßt.
  1077. Voraussetzung ist auch hier wieder, daß das Fenster für die AES existent, 
  1078. nämlich geöffnet, ist.
  1079.  
  1080.  
  1081. GLOBAL void get_border ( WINDOWP window, int obj, RECT *border )
  1082.  
  1083. Diese Funktion errechnet ein Rechteck, das ein Objekt umschließt, das sich in 
  1084. dem in eine Fenster-Struktur eingehängten Objekt befindet, sofern das 
  1085. dazugehörige Fenster geöffnet ist. Zu kompliziert !? Na gut, ein Beispiel: In 
  1086. einem geöffneten Fenster ist ein Objekt eingehängt (z. B. ein Dialog). In dem 
  1087. Dialog befindet sich ein Text-Objekt, von dem Sie gerne die Umrisse 
  1088. einschließlich Rand und Schatten (!) wissen wollen (z. B. um eine Dragbox zu 
  1089. zeichnen). Sie übergeben also den Fensterpointer, den Index des Textobjektes 
  1090. innerhalb des Objektbaums und einen Zeiger auf ein Rechteck. Fertig. (Ich gebe 
  1091. es ja zu: Die erste Erklärung war zwar kurz, aber etwas unverständlich...)
  1092.  
  1093.  
  1094. GLOBAL void lock_all ( WINDOWP wp )
  1095.  
  1096. Wenn alle Fenster gelockt werden sollen (gelockt heißt, daß sie zwar noch nach 
  1097. unten gebracht aber nicht mehr getoppt werden können), sollten Sie diese 
  1098. Funktion benutzen. Geben Sie statt einem NULL-Zeiger einem Fenster-Zeiger mit, 
  1099. wird dieses Fenster vor dem Locken ausgeschlossen. Dies ist z. B. bei der 
  1100. Programmierung modaler Dialoge in Fenstern interessant.
  1101.  
  1102.  
  1103. GLOBAL void unlock_all ( void )
  1104.  
  1105. Gelockte Fenster werden von dieser Routine wieder in den "Normal-Zustand" 
  1106. gebracht.
  1107.  
  1108.  
  1109. GLOBAL void draw_object ( WINDOWP window, int obj )
  1110.  
  1111. Eine weitere Funktion für eingehängte Objekte: Sie zeichnet das Objekt 
  1112. innerhalb des Fensters, während Rechteckliste und Scroll-Bereich beachtet 
  1113. werden.
  1114.  
  1115.  
  1116. GLOBAL void scroll_area ( const RECT *area, int dir, int delta )
  1117.  
  1118. Ein rechteckiger Bildschirmausschnitt wird um eine beliebige Anzahl Pixel in 
  1119. eine Richtung gescrollt, der jedoch nicht von der aktuellen Fenstergröße 
  1120. abhängig ist. dir gibt die Richtung an (HORIZONTAL, VERTICAL), während delta 
  1121. die Anzahl Pixel beinhaltet (negative Werte: abhängig von der Richtung nach 
  1122. links bzw. abwärts scrollen). Im Gegensatz zu scroll_window muß nicht der 
  1123. gesamte Fensterinhalt gescrollt werden.
  1124.  
  1125.  
  1126. GLOBAL void clr_area ( const RECT *area )
  1127.  
  1128. Ein Bildschirmausschnitt wird gelöscht, d. h. mit weiß gefüllt.
  1129.  
  1130.  
  1131. GLOBAL void clr_work ( WINDOWP window )
  1132. GLOBAL void clr_scroll ( WINDOWP window )
  1133. GLOBAL void clr_left ( WINDOWP window )
  1134. GLOBAL void clr_top ( WINDOWP window )
  1135. GLOBAL void clr_right ( WINDOWP window )
  1136. GLOBAL void clr_bottom ( WINDOWP window )
  1137.  
  1138. Die verschiedenen Bereiche eines Fensters werden gelöscht, wobei clr_left, 
  1139. clr_right, clr_top und clr_bottom sich auf die Fensterränder beziehen.
  1140.  
  1141.  
  1142. GLOBAL void set_redraw ( WINDOWP window, const RECT *area )
  1143.  
  1144. Eine Redraw-Meldung für einen bestimmten Bereich eines Fensters wird ausgelöst. 
  1145. Dies ist der sauberste Weg, einen Fensterbereich neu zeichnen zu lassen.
  1146.  
  1147.  
  1148. GLOBAL WINDOWP create_textwindow ( char *array, int doc_w, int doc_h, int kind, 
  1149. RECT *border )
  1150.  
  1151. Der GEM-Force-Window-Manager erleichtert zweifellos die Fensterverwaltung 
  1152. erheblich. Trotzdem mag es unnütz erscheinen, eine Standard-Fensteranwendung 
  1153. wie die Anzeige von Text in einem Fenster selbst zu programmieren. Aus diesem 
  1154. Grund wurde obige Funktion geschaffen. Sie erzeugt ein Textfenster und stellt 
  1155. (für den Programmierer unsichtbar) entsprechende Funktionen für die Verwaltung 
  1156. von Textfenstern zur Verfügung, indem diese in die Fenster-Struktur eingehängt 
  1157. werden.
  1158. Übergeben als erster Parameter wird ein char-Zeiger auf ein Array, in dem der 
  1159. Text zu finden ist, der angezeigt werden soll (meist werden Sie ein 2-
  1160. dimensionales char-Array haben; in diesem Fall reicht ein einfacher Cast auf 
  1161. einen einfachen char-Pointer).
  1162. Die nächsten beiden Einträge geben die Größe des Dokuments an, d. h. die 
  1163. maximale Anzahl Spalten und Zeilen. Bei char array [100][81] wären das 80 und 
  1164. 100, da ja ein Null-Byte am Zeilenende abgerechnet werden muß.
  1165. Der nächste Parameter legt wie üblich die Art des Fensters fest. Die Klasse 
  1166. wird automatisch auf CL_TEXT gesetzt.
  1167. Zum Schluß muß noch die Größe des Fensters (außen, nicht der Work-Bereich !) 
  1168. übergeben werden, die es beim Öffnen haben soll. Fertig ! Den Rest erledigt 
  1169. GEM-Force (siehe handle_window_events).
  1170.  
  1171.  
  1172. GLOBAL WINDOWP search_window ( int class, int mode )
  1173.  
  1174. Es folgen einige nützliche Funktionen für die Abfrage von Fensterattributen 
  1175. sowie das Finden von Fenstern.
  1176. Der erste Kandidat sucht ein Fenster einer bestimmten Klasse, wobei mode 
  1177. angibt, ob nur offene, geschlossene Fenster oder beide gesucht werden sollen 
  1178. (SRCH_CLOSED, SRCH_OPENED, SRCH_ANY).
  1179. Wurde kein passendes Fenster gefunden, wird ein NULL-Zeiger zurückgegeben.
  1180.  
  1181.  
  1182. GLOBAL WINDOWP find_window ( int handle )
  1183.  
  1184. Wenn Sie eine GEM-Fensternachricht bekommen haben und diese selbst auswerten 
  1185. wollen, müssen Sie zum mitgelieferten GEM-Handle wissen, welches GEM-Force-
  1186. Fenster zu diesem Handle gehört. Dazu übergeben Sie obiger Funktion das GEM-
  1187. Handle und bekommen den entsprechenden Window-Zeiger oder im Fehlerfall einen 
  1188. NULL-Zeiger zurückgeliefert.
  1189.  
  1190.  
  1191. GLOBAL WINDOWP find_xy_window ( const int x, const int y )
  1192.  
  1193. Bei der Fensterverwaltung kann es vorkommen, daß Sie ein Fenster suchen, das 
  1194. sich an einer bestimmten x- und y-Position befindet (z. B. bei einem erfolgten 
  1195. Mausklick). Dies erledigt diese Routine für Sie, wenn Sie die Koordinaten 
  1196. übergeben. Falls kein passendes GEM-Force-Fenster gefunden wurde, wird wieder 
  1197. ein NULL-Zeiger zurückgeliefert.
  1198.  
  1199.  
  1200. GLOBAL WINDOWP find_top ( void )
  1201.  
  1202. Einen Zeiger auf das oberste Fenster können Sie mit dieser Funktion ermitteln.
  1203.  
  1204.  
  1205. GLOBAL BOOLEAN is_top ( WINDOWP window )
  1206.  
  1207. Wie offensichtlich sein dürfte, kann mit dieser Routine abgefragt werden, ob 
  1208. ein Fenster das oberste ist.
  1209.  
  1210.  
  1211. GLOBAL BOOLEAN any_open ( BOOLEAN incl_closer )
  1212.  
  1213. Es kann getestet werden, ob irgendwelche Fenster offen sind, wobei noch 
  1214. spezifiziert werden kann, ob nur Fenster gesucht werden sollen, die auch eine 
  1215. Schließbox haben (TRUE). Sonst werden alle Fenster bei der Suche 
  1216. berücksichtigt.
  1217.  
  1218.  
  1219. GLOBAL int num_windows ( int class, int mode, WINDOWP winds[] )
  1220.  
  1221. Die Anzahl der Fenster einer oder aller Klassen (class = NIL) kann ermittelt 
  1222. werden. Dabei kann noch angegeben werden, ob offene oder geschlossene Fenster 
  1223. oder beide berücksichtigt werden sollen (mode SRCH_CLOSED, SRCH_OPENED, 
  1224. SRCH_ANY).
  1225. Wird ein Zeiger auf ein Array für Window-Zeiger übergeben, werden alle 
  1226. gefundenen Fensterzeiger hier eingetragen, so daß z. B. mit allen gefundenen 
  1227. Fenstern bestimmte Aktionen durchgeführt werden können. Andernfalls ist hier 
  1228. ein NULL-Zeiger zu übergeben.
  1229.  
  1230.  
  1231. GLOBAL int num_locked ( void )
  1232.  
  1233. Diese Funktion zählt die Fenster, deren Flags WI_LOCKED enthalten. (Zur 
  1234. Erinnerung: ein gelocktes Fenster kann zwar nach unten gebracht, nicht aber 
  1235. wieder getoppt werden.)
  1236.  
  1237.  
  1238. 6. Modul TOS
  1239. ============
  1240.  
  1241. Dieses Modul stellt ein paar nützliche Funktionen zur Verfügung. Einige dieser 
  1242. Funktionen sind zwar in einer GEM-Library etwas fehl am Platze, jedoch kann der 
  1243. ein oder andere sie vielleicht sinnvoll in TOS-Programmen einsetzen. Soll 
  1244. dieses Modul von GEM-Force genutzt werden, ist die Header-Datei "GF_TOS.H" zu 
  1245. importieren.
  1246.  
  1247.  
  1248. GLOBAL BOOLEAN copy ( const char *quelle, const char *ziel )
  1249.  
  1250. Es ist immer wieder nützlich, wenn man Dateien kopieren kann. Das erledigt 
  1251. diese Funktion für Sie. Die Quelle darf auch Wildcards enthalten; in diesem 
  1252. Falle wird vom Ziel nur der Pfad beachtet. Andernfalls muß die Zieldatei ein 
  1253. vollständiger Dateiname sein.
  1254. In jedem Fall wird bis auf einen kleinen Rest der gesamte verfügbare 
  1255. Hauptspeicher per malloc reserviert und über diesen Puffer munter kopiert. 
  1256. Anschließend wird der Speicherplatz natürlich wieder freigegeben.
  1257.  
  1258.  
  1259. GLOBAL BOOLEAN test_printer ( void )
  1260.  
  1261. Vor dem Drucken sollte man prüfen, ob der Drucker tatsächlich bereit dazu ist, 
  1262. weil sonst Probleme "vorprogrammiert" sind; diese kleine Routine gibt TRUE 
  1263. zurück wenn, der Drukker bereit ist, FALSE sonst.
  1264.  
  1265.  
  1266. GLOBAL BOOLEAN file_exist ( const char *filename ) 
  1267.  
  1268. Es wird geprüft, ob eine bestimmte Datei existiert.
  1269.  
  1270.  
  1271. GLOBAL BOOLEAN path_exist ( const char *pathname )
  1272.  
  1273. Es wird geprüft, ob ein bestimmter Pfad existiert.
  1274.  
  1275.  
  1276. GLOBAL void lprint ( char *string, BOOLEAN convert )
  1277.  
  1278. Eine Zeichenkette wird an den Drucker gesendet; anschließend wird ein CR/LF 
  1279. ausgelöst. Der zweite Parameter steuert dabei, ob deutsche Umlaute bereits 
  1280. richtig gedruckt werden sollen, was beim Drucken von Text sehr hilfreich ist. 
  1281. Wird FALSE übergeben, erfolgt keine Konvertierung.
  1282.  
  1283.  
  1284. GLOBAL void supervisor ( BOOLEAN mode )
  1285.  
  1286. Muß einmal betriebssystemnah programmiert werden, muß öfter zwischen 
  1287. Supervisor-Mode und dem normalen Modus umgeschaltet werden. Wird TRUE 
  1288. übergeben, wird der Supervisor-Mode angeschaltet, sonst wird er ausgeschaltet.
  1289. Wichtig ist, daß nicht "von Hand", d. h. ohne diese Funktion, eingeschaltet und 
  1290. dann mit der Funktion ausgeschaltet werden darf (und umgekehrt), da sich die 
  1291. Routine beim Einschalten statisch die alte Stack-Adresse merkt und diese beim 
  1292. Ausschalten wieder verwendet.
  1293.  
  1294.  
  1295. GLOBAL void poke ( long adr, char wert )
  1296. GLOBAL void wpoke ( long adr, int wert )
  1297. GLOBAL void lpoke ( long adr, long wert )
  1298. GLOBAL char peek ( long adr )
  1299. GLOBAL int wpeek ( long adr )
  1300. GLOBAL long lpeek ( long adr )
  1301.  
  1302. Wer schon einmal mit BASIC programmiert hat, wird diese Funktionen kennen: poke 
  1303. schreibt einen Wert an eine Speicheradresse (wpoke ein Wort, lpoke ein 
  1304. Langwort). peek dagegen liest den Inhalt einer Speicheradresse aus und gibt den 
  1305. Wert mit entsprechendem Typ zurück.
  1306.  
  1307.  
  1308. GLOBAL void cls ( void )
  1309.  
  1310. Nun folgen waschechte TOS-Funktionen: Bei der ersten wird der Bildschirm 
  1311. gelöscht und der Cursor in der linken oberen Ecke des Bildschirms positioniert.
  1312.  
  1313.  
  1314. GLOBAL void cursor_on ( void )
  1315. GLOBAL void cursor_off ( void )
  1316.  
  1317. Der Cursor wird an-/ausgeschaltet.
  1318.  
  1319.  
  1320. GLOBAL void at ( int zeile, int spalte )
  1321.  
  1322. Der Cursor wird an eine bestimmte Stelle auf dem Bildschirm gesetzt.
  1323.  
  1324.  
  1325. GLOBAL void print_at ( int zeile, int spalte, const char *text )
  1326.  
  1327. Ein Text wird an einer bestimmten Position auf dem Bildschirm ausgegeben. 
  1328. Anschließend erfolgt automatisch ein Zeilenvorschub.
  1329.  
  1330.  
  1331. GLOBAL void tab ( int spalte )
  1332.  
  1333. Der Cursor wird in der aktuellen Zeile in eine bestimmte Spalte gesetzt.
  1334.  
  1335.  
  1336. GLOBAL void print_tab ( int spalte, const char *text )
  1337.  
  1338. Ein Text wird an einer bestimmten Position in der aktuellen Zeile auf dem 
  1339. Bildschirm ausgegeben. Anschließend erfolgt automatisch ein Zeilenvorschub.
  1340.  
  1341.